package com.lambkit.plugin.smarthttp;

import cn.hutool.core.net.NetUtil;
import cn.hutool.setting.Setting;
import com.lambkit.core.LambkitApp;
import com.lambkit.core.LifecycleException;
import com.lambkit.core.pipeline.DefaultPipeLineFactory;
import com.lambkit.plugin.smarthttp.http.SmartHttpContext;
import com.lambkit.core.task.http.HttpWorkCenter;
import com.lambkit.core.service.impl.DefaultBeanFactory;
import com.lambkit.core.service.impl.DefaultClassOperateFactory;
import com.lambkit.core.service.impl.DefaultResourceFactory;
import org.smartboot.http.server.HttpBootstrap;
import org.smartboot.http.server.HttpRequest;
import org.smartboot.http.server.HttpResponse;
import org.smartboot.http.server.HttpServerHandler;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashSet;

/**
 * @author yangyong(孤竹行)
 */
public class SmartHttpApp extends LambkitApp {
    private HttpBootstrap bootstrap;

    public SmartHttpApp(String name) {
        super(name);
        context().setBeanFactory(new DefaultBeanFactory());
        context().setClassOperateFactory(new DefaultClassOperateFactory());
        context().setPipeLineFactory(new DefaultPipeLineFactory());
        context().setResourceFactory(new DefaultResourceFactory());
    }

    @Override
    public void start() throws LifecycleException {
        //初始化工作中心
        HttpWorkCenter workCenter = new HttpWorkCenter();
        context().addWorkCenter(workCenter.runOn(this));
        super.start();
    }

    @Override
    public void postStart() throws LifecycleException {
        Setting setting = new Setting("smarthttp.txt");
        int port = setting.getInt("smarthttp.port", 8080);
        boolean dev = setting.getBool("smarthttp.devMode", false);
        boolean bannerEnabled = setting.getBool("smarthttp.bannerEnabled", false);
        bootstrap = new HttpBootstrap();
        bootstrap.configuration().debug(dev)
                .bannerEnabled(bannerEnabled)
                .serverName("lambkit");

        if(setting.containsKey("smarthttp.threadNum")) {
            bootstrap.configuration()
                    .threadNum(setting.getInt("smarthttp.threadNum", 4));
        }
        if(setting.containsKey("smarthttp.readBufferSize")) {
            bootstrap.configuration()
                    .readBufferSize(setting.getInt("smarthttp.readBufferSize", 1024));
        }
        if(setting.containsKey("smarthttp.writeBufferSize")) {
            bootstrap.configuration()
                    .writeBufferSize(setting.getInt("smarthttp.writeBufferSize", 1024));
        }
        if(setting.containsKey("smarthttp.headerLimiter")) {
            bootstrap.configuration()
                    .headerLimiter(setting.getInt("smarthttp.headerLimiter", 100));
        }
        bootstrap.httpHandler(new HttpServerHandler() {
            @Override
            public void handle(HttpRequest request, HttpResponse response) throws IOException {
                String target = request.getRequestURI();
                if(target.indexOf(".") > 0) {
                    return;
                }

                HttpWorkCenter workCenter = context().getWorkCenter(HttpWorkCenter.class);
                workCenter.handle(new SmartHttpContext(request, response));
            }
        }).setPort(port).start();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        System.out.println("Lambkit SmartHttp Server Start Success.");
        super.postStart();

        String msg = "Server running on:\n";
        msg = msg + " > Local:   http://localhost:" + port;
        msg = msg + "\n";
        LinkedHashSet<String> ipList = NetUtil.localIpv4s();
        for(Iterator iterator = ipList.iterator(); iterator.hasNext(); msg = msg + "\n") {
            String ip = (String)iterator.next();
            msg = msg + " > Network: http://" + ip + ":" + port;
        }
        System.out.println(msg);
    }

    @Override
    public void stop() throws LifecycleException {
        super.stop();
        bootstrap.shutdown();
    }
}
